﻿#region Header

// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 2497 $</version>
// </file>

#endregion Header

namespace ICSharpCode.TextEditor.Util
{
    using System;
    using System.Collections.Generic;

    internal struct RedBlackTreeIterator<T> : IEnumerator<T>
    {
        #region Fields

        internal RedBlackTreeNode<T> node;

        #endregion Fields

        #region Constructors

        internal RedBlackTreeIterator(RedBlackTreeNode<T> node)
        {
            this.node = node;
        }

        #endregion Constructors

        #region Properties

        public T Current
        {
            get {
                if (node != null)
                    return node.val;
                else
                    throw new InvalidOperationException();
            }
        }

        public bool IsValid
        {
            get { return node != null; }
        }

        object System.Collections.IEnumerator.Current
        {
            get {
                return this.Current;
            }
        }

        #endregion Properties

        #region Methods

        void IDisposable.Dispose()
        {
        }

        public bool MoveBack()
        {
            if (node == null)
                return false;
            if (node.left != null) {
                node = node.left.RightMost;
            } else {
                RedBlackTreeNode<T> oldNode;
                do {
                    oldNode = node;
                    node = node.parent;
                    // we are on the way up from the left part, don't output node again
                } while (node != null && node.left == oldNode);
            }
            return node != null;
        }

        public bool MoveNext()
        {
            if (node == null)
                return false;
            if (node.right != null) {
                node = node.right.LeftMost;
            } else {
                RedBlackTreeNode<T> oldNode;
                do {
                    oldNode = node;
                    node = node.parent;
                    // we are on the way up from the right part, don't output node again
                } while (node != null && node.right == oldNode);
            }
            return node != null;
        }

        void System.Collections.IEnumerator.Reset()
        {
            throw new NotSupportedException();
        }

        #endregion Methods
    }
}